Skip to content

fix(dashboard): remove CORS wildcard from /api/pulse (PILOT-300)#23

Open
matthew-pilot wants to merge 1 commit into
mainfrom
openclaw/pilot-300-20260530-175036
Open

fix(dashboard): remove CORS wildcard from /api/pulse (PILOT-300)#23
matthew-pilot wants to merge 1 commit into
mainfrom
openclaw/pilot-300-20260530-175036

Conversation

@matthew-pilot
Copy link
Copy Markdown
Collaborator

What

The /api/pulse endpoint returned Access-Control-Allow-Origin: * with no authentication.

Why

Any external website visited by the dashboard operator can fetch('/api/pulse') cross-origin and read:

  • Real-time request count
  • 60-second pulse sample ring (request rate over time)

This leaks a server-load fingerprint — an attacker learns peak request rates and busy windows, which can inform timing of attacks or deployments.

Fix

Remove the permissive CORS header from this one endpoint. Same-origin requests (the dashboard JS) are unaffected — CORS only gates cross-origin fetches. The endpoint remains unauthenticated but is now scoped to same-origin access only.

Verification

go build ./...     ✓
go vet ./...       ✓
go test ./...      ✓ (all 18 packages pass)

Closes PILOT-300

The /api/pulse endpoint returned Access-Control-Allow-Origin: *
with no authentication, allowing any external website to poll
the registry's real-time request count and pulse samples via
cross-origin fetch.  This leaks a server-load fingerprint
(peak request rates, busy windows) to any attacker-controlled
page the dashboard operator visits.

Fix: drop the permissive CORS header from this endpoint.  Same-
origin requests (the dashboard JS that consumes /api/pulse)
are unaffected — CORS is only relevant for cross-origin fetches.
The endpoint remains unauthenticated but is now scoped to same-
origin access only.

Closes PILOT-300
@codecov
Copy link
Copy Markdown

codecov Bot commented May 30, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@matthew-pilot
Copy link
Copy Markdown
Collaborator Author

🤖 PR Status (matthew-pr-worker)

PR: #23fix(dashboard): remove CORS wildcard from /api/pulse (PILOT-300)
State: OPEN · Mergeable: ✅ CLEAN
Branch: openclaw/pilot-300-20260530-175036main

CI Checks (2/2 passing ✅)

Check Result
test ✅ passed (59s)
codecov/patch ✅ passed

Diff Stats

  • Files: 1 (dashboard/dashboard.go)
  • Changes: +0 / −1 (1 Δ)
  • Labels: none
  • Canary: not-configured (single-line CORS header removal)

Classification

Wave 1 · Action: pr-status + pr-explain · Tier: small


matthew-pr-worker tick 2026-05-30T18:20Z

@matthew-pilot
Copy link
Copy Markdown
Collaborator Author

🤖 PR Explain (matthew-pr-worker)

What this PR does (PILOT-300)

Problem: /api/pulse emitted Access-Control-Allow-Origin: * with no authentication. Any external website visited by the dashboard operator could fetch('/api/pulse') cross-origin and silently read:

  • Real-time request count
  • 60-second pulse sample ring (request rate over time)

This leaks a server-load fingerprint — an attacker learns peak request rates and busy windows, which can inform timing of attacks or deployments.

Fix: Remove the single Access-Control-Allow-Origin: * header from the /api/pulse handler (line 545 of dashboard/dashboard.go). Same-origin dashboard JS is unaffected — CORS only gates cross-origin fetches. The endpoint remains unauthenticated but is now scoped to same-origin access only.

Walkthrough

File Δ What changed
dashboard/dashboard.go +0/−1 Deleted w.Header().Set(Access-Control-Allow-Origin, *) from the /api/pulse handler.

Details

  • Single-line removal — no logic change, no new imports, no test changes needed (pulse endpoint tests don't assert CORS headers)
  • Builds clean: go build ./... ✅, go vet ./... ✅, go test ./... ✅ (all 18 packages)

Scope

  • Tier: small (1 file, +0/−1)
  • Verdict: ✅ minimal, targeted fix — removes an information leak vector

matthew-pr-worker tick 2026-05-30T18:20Z

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant